home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Developer Helper 1: Phil & Dave's Excellent CD
/
Excellent CD HFS.raw
/
Peripherals
/
MacinTalk
/
Interfaces
/
Lisa
/
source⁄SpeechAsm.text
< prev
Wrap
Text File
|
1989-04-13
|
13KB
|
392 lines
;-------------------------------------------------------------------------------;
; ;
; SpeechGlue - Interface for PASCAL programs using the ;
; Macintalk speech driver. ;
; ;
; Copyright 1984, Joseph Katz / Mark Barton. Not to be copied or ;
; distributed without the express written permission of the authors. ;
; ;
; Modification History: ;
; 06/02/85 - Modified only minutes before shipment of software ;
; supplement. Modified to separate code and data ;
; segments. This was done in a vast hurry. There ;
; are no known bugs in it, but it was not done cleanly. ;
; ;
; ;
;-------------------------------------------------------------------------------;
.NOLIST
.INCLUDE TLASM/SYSEQU.TEXT
.INCLUDE TLASM/SYSTRAPS.TEXT
.INCLUDE TLASM/SYSERR.TEXT
.INCLUDE TLASM/TOOLTRAPS.TEXT
.INCLUDE TLASM/TOOLEQU.TEXT
.LIST
RdrHandle .EQU 52 ;PBLOCK OFFSET OF HANDLE TO READER CODE
RulesFN .EQU 60 ;OFFSET TO READER EXCEPTIONS FILENAME POINTER
IDPitchMode .EQU 0
IDRate .EQU 2 ;ID=1 IS USED FOR KILLIO
IDSex .EQU 3 ;RESERVED FOR FUTURE IMPLEMENTATION
IDBaseline .EQU 4
fullUnitT .EQU -4000 ;ERROR CODE FOR DRIVER TABLE FULL
Pblock .EQU 0 ;OFFSET TO IOPARMBLOCK
ReaderHandle .EQU 66 ;OFFSET TO READER HANDLE
SpeechRfNum .EQU 70 ;OFFSET TO SPEECH DRIVER REFERENCE NUMBER
TalkRefNum .EQU 74 ;OFFSET TO TALK PACKAGE REFNUM
; FUNCTION SpeechOn(EXCPFile: Str255; VAR SpeechHandle: SpeechRecord): SpeechErr;
; Open speech driver. This is complicated by the need to arbitrate the
; driver unit number, which must be done prior to the actual device open.
.FUNC SpeechOn,1
MOVE.L A2,-(SP) ;SAVE A2 ON STACK
; Try to allocate driver globals area
MOVE.L #100,D0 ;GRAB 100 BYTES
_NewHandle
MOVE.L 8(SP),A1 ;GET SPEECH RECORD ADDR
MOVE.L A0,(A1) ;SAVE GLOBALS HANDLE
TST.W D0
BNE.S ONERROR ;IF ERROR, JUST RETURN
_HLock ;LOCK HANDLE
MOVE.L (A0),A2 ;SAVE POINTER TO GLOBALS
; Clear parm block
MOVEQ #0,D0
MOVEQ #24,D1
MOVE.L A2,A0
CLOOP MOVE.L D0,(A0)+
DBF D1,CLOOP
; Open MacinTalk resource file
CLR.W -(SP) ;SPACE FOR RETURN CODE
PEA DriverID ;NAME OF RESOURCE FILE
_OpenResFile ;OPEN IT
MOVE.W (SP)+,D0 ;GET RESOURCE FILE ID
BPL.S GOTRESFILE ;GOOD RETURN, BRANCH
MOVE.W ResErr,D0 ;SET RETURN CODE
ONERROR MOVE.L (SP)+,A2 ;RESTORE A2
MOVE.L (SP),8(SP) ;MOVE RETURN ADDR
ADDQ.L #8,SP ;FIX STACK
MOVE.W D0,4(SP) ;SET RETURN CODE
RTS ;AND GO AWAY
GOTRESFILE MOVE.W D0,TalkRefNum(A2) ;SAVE FILE REFNUM FOR LATER
; Set ResPreLoad to FALSE
MOVE.B #0,-(SP)
_SetResLoad
; Get handle to synthesizer resource; TYPE = DRVR, NAME=MacinTalk
CLR.L -(SP) ;SPACE FOR RETURN CODE
MOVE.L #'DRVR',-(SP) ;RESOURCE TYPE
PEA SpeechName ;RESOURCE NAME
_GetNamedResource ;GET DRIVER RESOURCE
MOVE.L (SP)+,A1 ;GET HANDLE TO RESOURCE (*** WAS AFTER BNE)
MOVE.W ResErr,D0 ;GOOD RETURN?
BNE.S ONERROR ;NO, BRANCH TO ERROR RETURN
; Restore ResPreLoad to TRUE
MOVE.B #1,-(SP)
_SetResLoad
; Find an empty slot in driver unit table (looking backwards from end)
MOVE.L uTableBase,A0 ;GET DRIVER UNIT TABLE BASE
ADDA.W #128,A0 ;START AT END+4 OF UNIT TABLE
MOVE.W #32,D0 ;LAST UNIT IN TABLE IS #31
@3 SUBQ.W #1,D0 ;REDUCE SLOT NUMBER
CMP.W #18,D0 ;NO FREE SLOTS BELOW UNIT 18
BGT.S @4
MOVE.W #fullUnitT,D0 ;SETUP ERROR CODE
BRA.S ONERROR ;AND GO AWAY
@4 CMPI.L #0,-(A0) ;IS SLOT EMPTY?
BNE.S @3 ;NO, KEEP LOOPING
; Change resource ID to new driver number, and load in resource data
MOVE.W D0,D1 ;DRIVER NUMBER
ADDQ.W #1,D1 ;
NEG.W D1 ;REF NUMBER
MOVE.W D1,SpeechRfNum(A2) ;SAVE REFERENCE NUMBER
MOVE.L A1,-(SP) ;RESOURCE HANDLE
MOVE.W D0,-(SP) ;NEW DRIVER NUMBER
MOVE.L #0,-(SP) ;DON'T CHANGE THE RESOURCE NAME
_SetResInfo
MOVE.L A1,-(SP)
_LoadResource
MOVE.W resErr,D0 ;FOR DEBUGGING
MOVE.L A1,A0 ;TRANSFER HANDLE TO A0
_HLock ;LOCK DRIVER CODE DOWN
; Get SpeechOn input parms from stack
MOVE.L (SP)+,A2 ;RESTORE A2
MOVE.L (SP)+,A0 ;GET RETURN ADDRESS
MOVE.L (SP)+,D0 ;GET ADDR OF SPEECHREC HANDLE
MOVE.L (SP)+,A1 ;GET EXCPS FILENAME PTR
MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
MOVE.L A2,-(SP) ;SAVE A2
MOVE.L D0,A2 ;ADDR OF DEV GLOBALS HANDLE
MOVE.L (A2),A2 ;DEVICE GLOBALS HANDLE
MOVE.L A2,-(SP) ;SAVE DEVICE GLOBALS HANDLE
MOVE.L (A2),A2 ;DEREF TO POINTER
; Build parm block and open the driver
LEA Pblock(A2),A0 ;A0 --> PARM BLOCK
MOVE.L A1,RulesFN(A0) ;SAVE PTR TO EXCPS FILENAME IN PBLOCK
LEA SpeechName,A1 ;A1 --> DRIVER NAME
MOVE.L A1,IOFileName(A0) ;STORE DRIVER NAME IN PARM BLOCK
CLR.W IODrvNum(A0) ;USE DEFAULT DRIVE
CLR.W IOFileType(A0) ;CLEAR TYPE/PERMISSIONS
CLR.L IOOwnBuf(A0) ;USE SYSTEM BUFFER
_Open
MOVE.W IOResult(A0),12(SP) ;SAVE RETURN CODE FROM OPEN
MOVE.L RdrHandle(A0),ReaderHandle(A2) ;SAVE HANDLE TO READER CODE
MOVE.L (SP)+,A0 ;UNLOCK DEVICE GLOBALS
_HUnlock
MOVE.L (SP)+,A2 ;RESTORE A2
RTS
SpeechName .BYTE 7
.ASCII '.SPEECH'
DriverID .BYTE 9
.ASCII 'MacinTalk'
; PROCEDURE SpeechOff(SpeechHandle: SpeechRecord);
; Closes speech driver.
.PROC SpeechOff
MOVE.L A2,-(SP) ;SAVE A2
MOVE.L 8(SP),A0 ;GET DEVICE GLOBALS HANDLE
_HLock
MOVE.L (A0),A2 ;DEREFERENCE TO POINTER
LEA Pblock(A2),A0 ;POINTER TO PARM BLOCK
_Close ,IMMED
MOVE.W TalkRefNum(A2),D0 ;MacinTalk REFNUM
BEQ.S @1 ;DONT CLOSE SYSTEM RES FILE
MOVE.W D0,-(SP)
_CloseResFile ;BYE-BYE
@1 MOVE.L 8(SP),A0 ;GET DEVICE GLOBALS HANDLE
_HUnlock ;UNLOCK IT
_DisposHandle ;TOSS IT
MOVE.L (SP)+,A2 ;RESTORE A2
MOVE.L (SP),4(SP) ;FIXUP STACK AND RETURN
ADDQ.L #4,SP
RTS
; PROCEDURE SpeechRate(SpeechHandle: SpeechRecord; Rate: Integer);
; Set the speaking rate in words/minute. Range and validity
; checking is done in SpeechPrime.
.PROC SpeechRate
MOVE.L (SP)+,D1 ;GET RETURN ADDR
MOVE.W (SP)+,D2 ;GET RATE PARM
MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS
MOVE.L D1,-(SP) ;RESTORE RETURN ADDR
MOVE.L A0,-(SP) ;SAVE DEVICE GLOBALS HANDLE
_HLock ;LOCK IT
MOVE.L (A0),A1 ;DEREF GLOBALS HANDLE
LINK A6,#-32 ;CREATE PARM BLOCK ON STACK
LEA -32(A6),A0 ;POINT A0 AT PARM BLOCK
MOVE.W SpeechRfNum(A1),IORefNum(A0) ;SET SPEECH REFNUM
MOVE.W #IDRate,CSCode(A0) ;SET RATE PARM ID
MOVE.W D2,CSParam(A0) ;STORE RATE PARM
_Control ,IMMED
UNLK A6 ;REMOVE DCE FROM STACK
MOVE.L (SP)+,A0 ;RESTORE DEVICE GLOBALS
_HUnlock ;UNLOCK IT
RTS
; PROCEDURE SpeechSex(SpeechHandle: SpeechRecord; SpeakerSex: Sex);
; Set the speaking sex as Male or Female.
.PROC SpeechSex
MOVEQ #0,D2 ;CLEAR
MOVE.L (SP)+,D1 ;GET RETURN ADDR
MOVE.B (SP)+,D2 ;GET SEX PARM (NOTE .B ON MOVE)
MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS
MOVE.L D1,-(SP) ;RESTORE RETURN ADDR
MOVE.L A0,-(SP) ;SAVE GLOBALS ON STACK
_HLock ;LOCK DEVICE GLOBALS
MOVE.L (A0),A1 ;DEREFERENCE TO POINTER
LINK A6,#-32 ;CREATE PARM BLOCK ON STACK
LEA -32(A6),A0 ;POINT A0 AT PARM BLOCK
MOVE.W SpeechRfNum(A1),IORefNum(A0) ;SET SPEECH REFNUM
MOVE.W #IDSex,CSCode(A0) ;SET SEX PARM ID
MOVE.W D2,CSParam(A0) ;STORE SEX PARM
_Control ,IMMED
UNLK A6 ;REMOVE PARM BLOCK FROM STACK
MOVE.L (SP)+,A0 ;RESTORE GLOBALS HANDLE
_HUnlock ;UNLOCK HANDLE
RTS
; PROCEDURE SpeechPitch(SpeechHandle: SpeechRecord; Pitch: Integer; Mode: F0Mode);
; Sets the baseline pitch and the F0 mode. All parameter
; validity and range checking is done in SpeechPrime routines.
.PROC SpeechPitch
MOVEQ #0,D2 ;CLEAR THE BUGGER
MOVE.L (SP)+,A1 ;GET RETURN ADDR
MOVE.B (SP)+,D2 ;GET PITCH MODE
MOVE.W (SP)+,D1 ;GET BASELINE PITCH
MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS HANDLE
MOVE.L A1,-(SP) ;RESTORE RETURN ADDR
MOVE.L A0,-(SP) ;SAVE GLOBALS ON STACK
_HLock ;LOCK GLOBALS
MOVE.L (A0),A1 ;DEREFERENCE
LINK A6,#-32 ;CREATE ROOM FOR PARM BLOCK
LEA -32(A6),A0
MOVE.W SpeechRfNum(A1),IORefNum(A0)
MOVE.W #IDPitchMode,CSCode(A0) ;SET MODE ID
MOVE.W D2,CSParam(A0) ;SET PITCH MODE
_Control ,IMMED
MOVE.W #IDBaseline,CSCode(A0) ;SET BASELINE ID
MOVE.W D1,CSPARAM(A0) ;SET BASELINE PITCH
_Control ,IMMED
UNLK A6
MOVE.L (SP)+,A0 ;RESTORE GLOBALS HANDLE
_HUnlock ;UNLOCK HANDLE
RTS
; FUNCTION MacinTalk(SpeechHandle: SpeechRecord; phonemes: Handle): SpeechErr;
; Macintalk glue passes phonemes handle to speech driver
; write routine.
.FUNC MacinTalk
MOVE.L (SP)+,D0 ;GET RETURN ADDR
MOVE.L (SP)+,A1 ;GET INPUT HANDLE
MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS HANDLE
MOVE.L D0,-(SP) ;RESTORE RETURN ADDR
MOVE.L A0,-(SP) ;SAVE ON STACK
_HLock ;LOCK GLOBALS HANDLE
MOVE.L A1,A0 ;COPY INPUT HANDLE TO A0
_GetHandleSize ;GET INPUT HANDLE SIZE IN D0
MOVE.L A2,-(SP)
MOVE.L 4(SP),A2
MOVE.L (A2),A2
LEA Pblock(A2),A0 ;POINT A0 TO PARM BLOCK
MOVE.W SpeechRfNum(A2),IORefNum(A0) ;STORE REF NUM
MOVE.L A1,IOBuffer(A0) ;STORE INPUT HANDLE
MOVE.L D0,IOByteCount(A0) ;STORE INPUT HANDLE LENGTH
_Write ,IMMED ;GO TO IT
MOVE.L (SP)+,A2 ;RESTORE A2
MOVE.L (SP)+,A0 ;RESTORE DEVICE GLOBALS HANDLE
MOVE.W D0,-(SP) ;SAVE WRITE RETURN CODE
_HUnlock ;UNLOCK GLOBALS
MOVE.W (SP)+,D0 ;RESTORE WRITE RETURN CODE
MOVE.W D0,4(SP) ;PUT RETURN CODE ON STACK
RTS
; FUNCTION Reader(theSpeech: SpeechHandle;
; English: Pointer;
; EnglishLen: LongInt;
; Output: Handle): Integer;
.FUNC Reader,2 ;READER GLUE
MOVE.L 16(SP),A0 ;GET DEVICE GLOBALS HANDLE
MOVE.L 12(SP),16(SP)
MOVE.L 8(SP),12(SP)
MOVE.L 4(SP),8(SP)
MOVE.L (SP),4(SP)
ADDQ.L #4,SP
_HLock
MOVE.L (A0),A0 ;DEREFERENCE GH
MOVE.L ReaderHandle(A0),A0 ;GET HANDLE TO READER CODE
_HLock ;LOCK CODE DOWN
MOVE.L (A0),A0 ;GET PTR TO CODE
JMP (A0) ;GO DO IT
RTS
.END